//// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
//package com.linqingying.gitcode.pullrequest.ui.toolwindow
//
//import com.intellij.collaboration.async.nestedDisposable
//import com.intellij.collaboration.ui.CollaborationToolsUIUtil
//import com.intellij.collaboration.ui.LoadingLabel
//import com.intellij.collaboration.ui.codereview.CodeReviewProgressTreeModelFromDetails
//import com.intellij.collaboration.ui.codereview.changes.CodeReviewChangeListComponentFactory
//import com.intellij.collaboration.ui.codereview.details.model.CodeReviewChangeListViewModel
//import com.intellij.collaboration.ui.codereview.list.error.ErrorStatusPanelFactory
//import com.intellij.collaboration.ui.codereview.list.error.ErrorStatusPresenter
//import com.intellij.collaboration.ui.util.bindContentIn
//import com.intellij.ide.DataManager
//import com.intellij.openapi.actionSystem.ActionGroup
//import com.intellij.openapi.actionSystem.ActionManager
//import com.intellij.openapi.project.Project
//import com.intellij.openapi.vcs.FilePath
//import com.intellij.openapi.vcs.changes.Change
//import com.intellij.openapi.vcs.changes.ChangesUtil
//import com.intellij.openapi.vcs.changes.ui.ChangesTree
//import com.intellij.openapi.vcs.changes.ui.VcsTreeModelData
//import com.intellij.ui.ScrollPaneFactory
//import com.intellij.ui.ScrollableContentBorder
//import com.intellij.ui.Side
//import com.intellij.ui.components.panels.Wrapper
//import com.intellij.util.ui.UIUtil
//import kotlinx.coroutines.CoroutineScope
//import kotlinx.coroutines.flow.flowOf
//import com.linqingying.gitcode.i18n.GitCodeBundle
//import com.linqingying.gitcode.pullrequest.action.GCPRActionKeys
//import com.linqingying.gitcode.pullrequest.ui.details.GCPRDetailsComponentFactory
//import com.linqingying.gitcode.pullrequest.ui.details.model.GCPRChangeListViewModel
//import com.linqingying.gitcode.pullrequest.ui.details.model.GCPRDetailsLoadingViewModel
//import com.linqingying.gitcode.pullrequest.ui.details.model.impl.GCPRChangesViewModel
//import com.linqingying.gitcode.pullrequest.ui.details.model.impl.GCPRDetailsViewModel
//import com.linqingying.gitcode.pullrequest.ui.toolwindow.model.GCPRInfoViewModel
//import javax.swing.Action
//import javax.swing.JComponent
//
//internal class GCPRViewComponentFactory(actionManager: ActionManager,
//                                        private val project: Project,
//                                        private val vm: GCPRInfoViewModel) {
//
//  private val reloadDetailsAction = actionManager.getAction("GitCode.PullRequest.Details.Reload")
//
//  fun create(cs: CoroutineScope): JComponent =
//    cs.createInfoLoadingComponent().apply {
//      DataManager.registerDataProvider(this) { dataId ->
//        when {
//          GCPRActionKeys.PULL_REQUEST_ID.`is`(dataId) -> vm.pullRequest
//          GCPRActionKeys.PULL_REQUEST_URL.`is`(dataId) -> vm.pullRequestUrl
//          GCPRDetailsLoadingViewModel.DATA_KEY.`is`(dataId) -> vm
//          else -> null
//        }
//      }
//    }
//
//  private fun CoroutineScope.createInfoLoadingComponent(): JComponent {
//    val cs = this
//    return Wrapper(LoadingLabel()).apply {
//      isOpaque = false
//      background = UIUtil.getListBackground()
//
//      bindContentIn(cs, vm.detailsVm) { result ->
//        result.result?.fold(
//          onSuccess = { createInfoComponent(it) },
//          onFailure = { createInfoErrorComponent(it) }
//        ) ?: LoadingLabel()
//      }
//    }
//  }
//
//  private fun CoroutineScope.createInfoComponent(detailsVm: GCPRDetailsViewModel): JComponent {
//    return GCPRDetailsComponentFactory.create(this,
//                                              project,
//                                              detailsVm,
//                                              createChangesComponent(detailsVm.changesVm)).apply {
//      reloadDetailsAction.registerCustomShortcutSet(this, nestedDisposable())
//    }.let {
//      CollaborationToolsUIUtil.wrapWithProgressStripe(this, detailsVm.isUpdating, it)
//    }
//  }
//
//  private fun CoroutineScope.createInfoErrorComponent(error: Throwable): JComponent {
//    val errorPresenter = object : ErrorStatusPresenter.Text<Throwable> {
//      override fun getErrorTitle(error: Throwable): String = GitCodeBundle.message("cannot.load.details")
//      override fun getErrorDescription(error: Throwable): String? = error.localizedMessage
//      override fun getErrorAction(error: Throwable): Action = vm.detailsLoadingErrorHandler.getActionForError(error)
//    }
//    val errorPanel = ErrorStatusPanelFactory.create(this, flowOf(error), errorPresenter)
//    return CollaborationToolsUIUtil.moveToCenter(errorPanel)
//  }
//
//  private fun CoroutineScope.createChangesComponent(changesVm: GCPRChangesViewModel): JComponent {
//    val cs = this
//    return Wrapper(LoadingLabel()).apply {
//      bindContentIn(cs, changesVm.changeListVm) { res ->
//        res.result?.let {
//          it.fold(onSuccess = {
//            createChangesPanel(it)
//          }, onFailure = {
//            createChangesErrorComponent(changesVm, it)
//          })
//        } ?: LoadingLabel()
//      }
//    }
//  }
//
//  private fun CoroutineScope.createChangesPanel(changeListVm: GCPRChangeListViewModel): JComponent {
//    val progressModel = CodeReviewProgressTreeModelFromDetails(this, changeListVm)
//    val tree = CodeReviewChangeListComponentFactory.createIn(this, changeListVm, progressModel,
//                                                             GitCodeBundle.message("pull.request.does.not.contain.changes"))
//
//    val scrollPane = ScrollPaneFactory.createScrollPane(tree, true)
//    val stripe = CollaborationToolsUIUtil.wrapWithProgressStripe(this, changeListVm.isUpdating, scrollPane)
//    ScrollableContentBorder.setup(scrollPane, Side.TOP_AND_BOTTOM, stripe)
//
//    DataManager.registerDataProvider(stripe) { dataId ->
//      when {
//        tree.isShowing ->
//          when {
//            GCPRChangeListViewModel.DATA_KEY.`is`(dataId) -> changeListVm
//            CodeReviewChangeListViewModel.DATA_KEY.`is`(dataId) -> changeListVm
//            else -> null
//          } ?: tree.getData(dataId)
//        else -> null
//      }
//    }
//    tree.installPopupHandler(ActionManager.getInstance().getAction("GitCode.PullRequest.Changes.Popup") as ActionGroup)
//
//    return stripe
//  }
//
//  private fun CoroutineScope.createChangesErrorComponent(changesVm: GCPRChangesViewModel, error: Throwable): JComponent {
//    val errorPresenter = object : ErrorStatusPresenter.Text<Throwable> {
//      override fun getErrorTitle(error: Throwable): String = GitCodeBundle.message("cannot.load.changes")
//      override fun getErrorDescription(error: Throwable): String? = error.localizedMessage
//      override fun getErrorAction(error: Throwable): Action = changesVm.changesLoadingErrorHandler.getActionForError(error)
//    }
//    val errorPanel = ErrorStatusPanelFactory.create(this, flowOf(error), errorPresenter)
//    return CollaborationToolsUIUtil.moveToCenter(errorPanel)
//  }
//}
